﻿using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using MT.Common;
using MT.Common.Helper;
using MT.Common.Helpers;
using MT.Common.Log;
using MT.Common.QueueTask;
using MT.DAL.Abstract.UserCenter;
using MT.Models.Entity;
using MT.Models.Enumerate;
using MT.Rest.Core.Models.UserCenter;
using System;
using System.Linq;
using System.Threading.Tasks;
using Xbb.Common.Helpers;

namespace MT.Rest.Controllers.UserCenter
{
    /// <summary>
    /// 用户管理
    /// </summary>
    public class UserController : AuthApiController
    {
        private readonly IUserLogService _userLogService;
        private readonly IUserService _userService;
        private readonly ISmsService _smsService;
        private readonly IBackgroundTaskQueue _queue;
        public UserController(IUserLogService userLogService, IUserService userService, ISmsService smsService, IBackgroundTaskQueue backgroundTaskQueue)
        {
            _userLogService = userLogService;
            _userService = userService;
            _smsService = smsService;
            _queue = backgroundTaskQueue;
        }


        /// <summary>
        /// 获取用户信息
        /// </summary>
        [HttpGet("{id}")]
        public async Task<UserInfo> GetUserInfo(int id)
        {
            var user = await _userService.GetUser(id);

            var model = MapperHelper<User, UserInfo>.Map(user);
            var userBusinessRoles = await _userService.GetUserBusinessRoleByUserIdAsync(user.Id);
            model.UserBusinessRoleInfos = MapperHelper<UserBusinessRole, UserBusinessRoleInfo>.MapList(userBusinessRoles);
            var userRoles = await _userService.GetUserRoleByUserIdAsync(user.Id, null);
            model.UserRoleInfos = MapperHelper<UserRole, UserRoleInfo>.MapList(userRoles);
            return model;
        }


        /// <summary>
        /// 获取用户信息
        /// </summary>
        [HttpGet("owner")]
        public async Task<UserInfo> GetOwnerUserInfo()
        {
            return await GetUserInfo(this.CurrentUser.Id);
        }

        /// <summary>
        /// 用户列表  
        /// </summary>
        /// <param name="index">页码</param>
        /// <param name="pageSize">页长度</param>
        /// <param name="name">姓名</param>
        /// <param name="institutionId">机构  todo</param>
        [HttpGet("page/{index}")]
        public async Task<PageModel<UserInfo>> GetPageAsync(int index, int pageSize, string name = null, int? institutionId = null)
        {
            var result = await _userService.GetPageAsync(index, pageSize, name, institutionId);

            var mapResult = MapperHelper<PageModel<User>, PageModel<UserInfo>>.Map(result);
            if (mapResult?.Items == null || mapResult.Items.Count <= 0)
            {
                return null;
            }

            foreach (var item in mapResult.Items)
            {
                item.UserBusinessRoleInfos = MapperHelper<UserBusinessRole, UserBusinessRoleInfo>.MapList(await _userService.GetUserBusinessRoleByUserIdAsync(item.Id));
            }
            return mapResult;
        }

        /// <summary>
        /// 获取店铺用户
        /// </summary>
        [HttpGet("{storeId}/page/{index}")]
        public async Task<PageModel<UserInfo>> GetPageTwoAsync(int index, int pageSize, int storeId, string keyword = null, string businessRoleDic = null)
        {
            var result = await _userService.GetPageAsync(index, pageSize, keyword, storeId, businessRoleDic);
            var mapResult = MapperHelper<PageModel<User>, PageModel<UserInfo>>.Map(result);
            return mapResult;
        }


        /// <summary>
        /// 修改密码
        /// </summary>
        /// <returns></returns>
        [HttpPut("pwd")]
        public async Task<ActionResult> UpdatePwdAsync(UpdatePwdRequest request)
        {
            if (request == null)
            {
                return BadRequest(new { Code = ErrorCode.InternalError, Msg = ErrorCode.InternalError.GetEnumDesc() });
            }

            var sms = await _smsService.GetAsync(request.PhoneNumber, EnumHelper.GetEnumDesc(SmsTypeEnum.ModifyPassword));
            if (sms == null || sms != request.Code)
            {
                return BadRequest(new { Code = ErrorCode.VerificationCodeError, Msg = ErrorCode.VerificationCodeError.GetEnumDesc() });
            }

            await _smsService.DeleteAsync(request.PhoneNumber, EnumHelper.GetEnumDesc(SmsTypeEnum.ModifyPassword));
            var userId = this.CurrentUser.Id;
            var model = await _userService.GetUser(userId);
            if (model == null)
            {
                return BadRequest(new { Code = ErrorCode.UserNotExist, Msg = ErrorCode.UserNotExist.GetEnumDesc() });
            }

            model.PasswordHash = new string(PasswordHelper.CreatePasswordHash(request.Password, model.PasswordSalt));
            await _userService.UpdateAsync(model);

            _queue.QueueBackgroundWorkItem(async (o) =>
            {
                await _userLogService.CreateUserOperateLogAsync(new UserOperateLog()
                {
                    ClientTypeDic = this.CurrentUser.ClientTypeDic,
                    Delete = false,
                    InstitutionId = 0,
                    Ip = Ip,
                    ModelType = (byte)ModelTypeEnum.User,
                    UserId = this.CurrentUser.Id,
                    Type = (byte)OperateTypeEnum.PwdUpdate,
                    OperateContent = "用户管理/密码修改",
                    OperateIds = model.Id.ToString()
                });
            });
            return Ok();
        }

        /// <summary>
        /// 找回密码
        /// </summary>
        [HttpPost("retrieve/pwd"), AllowAnonymous]
        public async Task<ActionResult> RetrievePwdAsync(RetrievePwdRequest request)
        {
            if (request == null)
            {
                return BadRequest(new { Code = ErrorCode.InternalError, Msg = ErrorCode.InternalError.GetEnumDesc() });
            }
            var sms = await _smsService.GetAsync(request.PhoneNumber, EnumHelper.GetEnumDesc(SmsTypeEnum.RetrievePassword));
            if (sms == null || sms != request.Code)
            {

                return BadRequest(new { Code = ErrorCode.VerificationCodeError, Msg = ErrorCode.VerificationCodeError.GetEnumDesc() });
            }

            var model = await _userService.GetByPhoneNumber(request.PhoneNumber);
            if (model == null)
            {
                return BadRequest(new { Code = ErrorCode.UserNotExist, Msg = ErrorCode.UserNotExist.GetEnumDesc() });
            }

            model.PasswordHash = new string(PasswordHelper.CreatePasswordHash(request.Password, model.PasswordSalt));
            await _userService.UpdateAsync(model);

            _queue.QueueBackgroundWorkItem(async (o) =>
            {
                await _userLogService.CreateUserOperateLogAsync(new UserOperateLog()
                {
                    ClientTypeDic = this.CurrentUser.ClientTypeDic,
                    Delete = false,
                    InstitutionId = 0,
                    Ip = Ip,
                    ModelType = (byte)ModelTypeEnum.User,
                    UserId = this.CurrentUser.Id,
                    Type = (byte)OperateTypeEnum.PwdRetrieve,
                    OperateContent = "用户管理/找回密码",
                    OperateIds = model.Id.ToString()
                });
            });
            return Ok();
        }


        /// <summary>
        /// 操作记录
        /// </summary>
        [HttpGet("operateLog/page/{index}")]
        public async Task<PageModel<UserOperateLogInfo>> GetOperateLogPageAsync(int index, int pageSize, string name = null, DateTime? startTime = null, DateTime? endTime = null)
        {
            endTime = endTime?.AddDays(1);
            var result = await _userLogService.GetOperateLogPageAsync(index, pageSize, name, startTime, endTime);
            var mapResult = MapperHelper<PageModel<UserOperateLog>, PageModel<UserOperateLogInfo>>.Map(result);
            if (mapResult == null)
                return mapResult;

            var users = await _userService.GetCacheByIdsAsync(mapResult.Items.Select(s => s.UserId).ToList());
            foreach (var item in mapResult.Items)
            {
                item.User = MapperHelper<User, UserInfoLite>.Map(users.FirstOrDefault(s => s.Id == item.UserId));
            }
            return mapResult;
        }

        /// <summary>
        /// 登录记录
        /// </summary>
        [HttpGet("loginLog/page/{index}")]
        public async Task<PageModel<UserLoginLogInfo>> GetLoginLogPageAsync(int index, int pageSize, string name = null, DateTime? startTime = null, DateTime? endTime = null)
        {
            var result = await _userLogService.GetrLoginLogPageAsync(index, pageSize, name, startTime, endTime);
            var mapResult = MapperHelper<PageModel<UserLoginLog>, PageModel<UserLoginLogInfo>>.Map(result);
            var users = await _userService.GetCacheByIdsAsync(mapResult.Items.Select(s => s.UserId).ToList());
            foreach (var item in mapResult.Items)
            {
                item.User = MapperHelper<User, UserInfoLite>.Map(users.FirstOrDefault(s => s.Id == item.UserId));
            }

            return mapResult;
        }
    }
}